from decimal import Decimal
import logging
import uuid
from rest_framework.views import APIView
from rest_framework import generics, permissions,serializers,status
from rest_framework.response import Response
from rest_framework.exceptions import APIException
from rest_framework.permissions import IsAuthenticated
from django.db import transaction
from django.db.models import Q, F, Sum
from django.shortcuts import get_object_or_404

from apps.chefs.models import DjChef
from .models import DjChefWallet, DjWalletTransaction,DjChefBankCard, DjWithdrawal
from .serializers import (
    ChefWalletSerializer, 
    ChefWithdrawalSerializer,
    DjWithdrawalSerializer, 
    DjWalletTransactionSerializer,
    ChefWithdrawalReviewSerializer,
    BankCardSerializer,
    BankCardCreateSerializer,
    WithdrawalSerializer,
    WithdrawalInfoSerializer)
from .services import process_payment

logger = logging.getLogger(__name__)



#以下厨师端

class ChefWalletView(generics.RetrieveAPIView):
    """厨师钱包信息（使用DjChef ID关联钱包）"""
    serializer_class = ChefWalletSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_object(self):
        try:
            # 1. 获取当前登录用户（accounts.User模型）
            user = self.request.user
            logger.info(f"用户[{user.id}]查询厨师钱包信息")
            
            # 2. 通过用户关联到厨师模型（chefs.DjChef）
            try:
                # 直接通过OneToOneField反向关联获取厨师实例
                chef = DjChef.objects.get(user=user)
                logger.info(f"关联到厨师[{chef.id}]，开始查询钱包")
            except DjChef.DoesNotExist:
                logger.error(f"用户[{user.id}]未关联任何厨师账号")
                raise APIException("当前用户未注册为厨师，请先完成厨师认证")
            
            # 3. 关键修改：通过厨师ID（DjChef.id）查询关联的钱包
            try:
                # 使用chef.id作为关联条件，而非之前的对象关联
                wallet = DjChefWallet.objects.get(chef_id=chef.id)
                return wallet
            except DjChefWallet.DoesNotExist:
                logger.error(f"厨师[{chef.id}]未创建钱包记录")
                raise APIException("钱包尚未创建，请联系客服开通")
                
        except APIException as e:
            # 传递自定义异常
            raise e
        except Exception as e:
            logger.error(f"钱包查询异常: {str(e)}", exc_info=True)
            raise APIException("获取钱包信息失败，请稍后重试")

class ChefWithdrawalView(generics.CreateAPIView):
    """厨师提现申请（优化版）"""
    serializer_class = ChefWithdrawalSerializer
    permission_classes = [IsAuthenticated]

    def get_serializer_context(self):
        context = super().get_serializer_context()
        context['chef'] = self.get_chef()
        return context

    def get_chef(self):
        """获取当前用户关联的厨师资料"""
        return get_object_or_404(
            DjChef, 
            user=self.request.user
        )

    def post(self, request, *args, **kwargs):
        """处理提现申请的POST请求"""
        try:
            chef = self.get_chef()
            wallet = chef.payment_wallet
            if not wallet:
                return Response(
                    {"detail": "未找到支付钱包，请先创建钱包"},
                    status=status.HTTP_400_BAD_REQUEST
                )

            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            
            return Response(
                {"detail": "提现申请提交成功", "data": serializer.data},
                status=status.HTTP_201_CREATED
            )
                
        except Exception as e:
            logger.error(f"提现处理失败: {str(e)}", exc_info=True)
            return Response(
                {"detail": "服务器处理失败"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def perform_create(self, serializer):
        """保存提现记录并同步更新余额+创建交易流水"""
        chef = self.get_chef()
        amount = Decimal(str(serializer.validated_data['amount']))
        bank_card = serializer.validated_data.get('bank_card')
        
        if not bank_card:
            raise serializers.ValidationError({"bank_card": "请选择提现银行卡"})
        
        # 使用事务确保原子性
        with transaction.atomic():
            # 获取钱包实例
            wallet = chef.payment_wallet
            
            # 1. 保存提现记录（会自动计算手续费，见DjWithdrawal.save()）
            withdrawal = serializer.save(
                wallet=wallet,
                chef_id=chef.id,
                status='pending',
                account_name=bank_card.card_holder,
                account_number=bank_card.card_number
            )
            
            # 2. 原子扣减余额（含DjChef和DjChefWallet，使用F()避免并发问题）
            # 扣减金额 = 提现金额 + 手续费（如果手续费由厨师承担）
            total_deduct = amount + withdrawal.fee  # 从模型save()中获取计算后的手续费
            
            # 更新钱包余额
            DjChefWallet.objects.filter(id=wallet.id).update(
                balance=F('balance') - total_deduct
            )
            # 更新厨师表余额（如果业务需要双写）
            DjChef.objects.filter(id=chef.id).update(
                balance=F('balance') - total_deduct
            )
            
            # 3. 创建提现交易流水
            transaction_id = f"WITHDRAW-{uuid.uuid4().hex[:16].upper()}"  # 生成唯一流水号
            DjWalletTransaction.objects.create(
                chef_id=chef.id,
                wallet=wallet,
                transaction_type='withdrawal',  # 提现类型
                amount=-total_deduct,  # 负数表示支出
                transaction_id=transaction_id,
                related_withdrawal=withdrawal,  # 关联提现记录
                note=f"提现申请：{amount}元，手续费：{withdrawal.fee}元",
                admin_note=f"提现申请ID：{withdrawal.id}"
            )
            
            logger.info(
                f"厨师 {chef.id} 提交提现申请成功，"
                f"金额: {amount}, 手续费: {withdrawal.fee}, "
                f"卡号: {bank_card.card_number[-4:]}, 流水号: {transaction_id}"
            )


class ChefWithdrawalReviewView(generics.UpdateAPIView):
    """处理提现审核（通过/拒绝）"""
    queryset = DjWithdrawal.objects.all()
    serializer_class = ChefWithdrawalReviewSerializer  # 需要自定义（仅包含status和failure_reason）
    permission_classes = [IsAuthenticated]  # 实际应限制为管理员权限

    def perform_update(self, serializer):
        """更新提现状态，处理审核不通过时的余额回滚"""
        withdrawal = self.get_object()
        old_status = withdrawal.status
        new_status = serializer.validated_data['status']
        failure_reason = serializer.validated_data.get('failure_reason', '')

        # 仅处理状态从pending变更为失败/取消的情况
        if old_status == 'pending' and new_status in ['failed', 'cancelled']:
            with transaction.atomic():
                # 1. 计算需要回滚的金额（原扣减金额 = 提现金额 + 手续费）
                total_rollback = withdrawal.amount + withdrawal.fee
                
                # 2. 原子回滚余额
                DjChefWallet.objects.filter(id=withdrawal.wallet.id).update(
                    balance=F('balance') + total_rollback
                )
                DjChef.objects.filter(id=withdrawal.chef_id).update(
                    balance=F('balance') + total_rollback
                )
                
                # 3. 创建提现失败退款流水
                transaction_id = f"WITHDRAW-ROLLBACK-{uuid.uuid4().hex[:16].upper()}"
                DjWalletTransaction.objects.create(
                    chef_id=withdrawal.chef_id,
                    wallet=withdrawal.wallet,
                    transaction_type='withdrawal_failed',  # 提现失败退款类型
                    amount=total_rollback,  # 正数表示收入（回滚）
                    transaction_id=transaction_id,
                    related_withdrawal=withdrawal,
                    note=f"提现失败退款：{withdrawal.amount}元，手续费：{withdrawal.fee}元，原因：{failure_reason}",
                    admin_note=f"提现ID：{withdrawal.id}，状态从{old_status}变更为{new_status}"
                )

        # 4. 更新提现记录状态（会自动更新processed_at，见DjWithdrawal.save()）
        serializer.save(
            failure_reason=failure_reason,
            processed_at=timezone.now() if new_status in ['completed', 'failed'] else None
        )
        
        logger.info(
            f"提现记录 {withdrawal.id} 状态更新：{old_status} -> {new_status}, "
            f"厨师ID：{withdrawal.chef_id}"
        )
        
class ChefWalletCreateView(generics.CreateAPIView):
    """
    厨师开通钱包视图
    当用户点击“开通钱包”时，为当前厨师创建关联的DjChefWallet记录
    """
    serializer_class = ChefWalletSerializer
    permission_classes = [IsAuthenticated]

    def create(self, request, *args, **kwargs):
        try:
            user = request.user
            logger.info(f"用户[{user.id}]请求开通钱包")

            # 1. 验证用户是否已关联厨师身份
            if not hasattr(user, 'djchef_profile'):
                logger.error(f"用户[{user.id}]未关联厨师身份，无法开通钱包")
                raise APIException("请先完成厨师认证，再开通钱包")

            chef = user.djchef_profile

            # 2. 检查是否已开通钱包
            if hasattr(chef, 'payment_wallet'):
                # 若已开通，返回现有钱包信息
                wallet = chef.payment_wallet
                logger.info(f"用户[{user.id}]已开通钱包，钱包ID: {wallet.id}")
                return Response(
                    ChefWalletSerializer(wallet).data,
                    status=status.HTTP_200_OK
                )

            # 3. 为厨师创建新钱包（默认初始值）
            wallet = DjChefWallet.objects.create(
                chef=chef,  # 关联当前厨师
                balance=0.00,  # 初始余额为0
                frozen_amount=0.00,
                total_earned=0.00,
                total_withdrawn=0.00,
                # 其他字段使用模型默认值（如每日提现限额、最低提现金额等）
            )
            logger.info(f"用户[{user.id}]钱包创建成功，钱包ID: {wallet.id}")

            # 4. 返回新创建的钱包信息
            return Response(
                ChefWalletSerializer(wallet).data,
                status=status.HTTP_201_CREATED
            )

        except APIException as e:
            return Response(
                {"detail": str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
        except Exception as e:
            logger.error(f"用户[{user.id}]开通钱包失败: {str(e)}", exc_info=True)
            return Response(
                {"detail": "开通钱包失败，请稍后重试"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    

class ChefWithdrawalHistoryView(generics.ListAPIView):
    """
    厨师提现历史记录视图
    获取当前已认证厨师的所有提现记录及收入信息（支持分页）
    """
    serializer_class = DjWithdrawalSerializer
    permission_classes = [IsAuthenticated]

    def list(self, request, *args, **kwargs):
        try:
            # 获取当前登录用户
            current_user = request.user
            logger.info(f"用户[{current_user.id}]尝试查询提现历史记录")

            # 1. 检查用户是否关联了厨师资料
            if not hasattr(current_user, 'djchef_profile'):
                logger.error(f"用户[{current_user.id}]未关联厨师资料，拒绝查询")
                raise APIException("请先完成厨师注册")

            # 获取关联的厨师资料
            chef_profile = current_user.djchef_profile

            # 2. 检查厨师是否已认证
            if chef_profile.verification_status != 'verified':
                logger.warning(
                    f"用户[{current_user.id}]厨师认证状态为[{chef_profile.verification_status}]，拒绝查询"
                )
                raise APIException("请先完成厨师认证")

            # 3. 检查厨师是否有可用钱包
            if not hasattr(chef_profile, 'payment_wallet') or not chef_profile.payment_wallet:
                logger.warning(f"用户[{current_user.id}]未开通钱包，返回空记录")
                return Response(
                    {
                        "count": 0, 
                        "results": [],
                        "income_summary": {  # 收入统计
                            "total_income": "0.00",
                            "order_income": "0.00",
                            "bonus_income": "0.00",
                            "total_withdrawn": "0.00",
                            "current_balance": "0.00"
                        },
                        "recent_income_transactions": []  # 最近收入记录
                    },
                    status=status.HTTP_200_OK
                )

            # 获取厨师钱包
            chef_wallet = chef_profile.payment_wallet

            # 4. 查询该钱包下的所有提现记录（按申请时间倒序）
            withdrawal_records = DjWithdrawal.objects.filter(

                wallet=chef_wallet
            ).order_by('-requested_at')
            logger.info(f"钱包[{chef_wallet.id}]下的提现记录数量：{withdrawal_records.count()}")  # 关键日志
            income_transactions = DjWalletTransaction.objects.filter(
                wallet=chef_wallet,
                transaction_type__in=['order_income', 'bonus']
            )
            logger.info(f"钱包[{chef_wallet.id}]下的收入交易数量：{income_transactions.count()}")  # 关键日志
            # 5. 计算收入相关统计数据
            # 5.1 总收入统计（订单收入+奖励金）
            income_transactions = DjWalletTransaction.objects.filter(
                wallet=chef_wallet,
                transaction_type__in=['order_income', 'bonus']
            )
            
            total_income = income_transactions.aggregate(
                total=Sum('amount')
            )['total'] or 0
            
            order_income = income_transactions.filter(
                transaction_type='order_income'
            ).aggregate(
                total=Sum('amount')
            )['total'] or 0
            
            bonus_income = income_transactions.filter(
                transaction_type='bonus'
            ).aggregate(
                total=Sum('amount')
            )['total'] or 0

            # 5.2 总提现金额
            total_withdrawn = DjWithdrawal.objects.filter(
                wallet=chef_wallet,
                status='completed'
            ).aggregate(
                total=Sum('amount')
            )['total'] or 0

            # 5.3 最近收入记录（取最近5条）
            recent_income_transactions = DjWalletTransaction.objects.filter(
                wallet=chef_wallet,
                transaction_type__in=['order_income', 'bonus']
            ).order_by('-created_at')[:5]

            # 打印实际查询到的记录ID
            logger.info(f"最近收入记录ID列表：{[t.id for t in recent_income_transactions]}")
            income_serializer = DjWalletTransactionSerializer(recent_income_transactions, many=True)
            logger.info(f"收入交易序列化数据：{income_serializer.data}")  # 新增日志

            # 6. 处理提现记录分页
            page = self.paginate_queryset(withdrawal_records)
            if page is not None:
                withdrawal_serializer = self.get_serializer(page, many=True)
                paginated_response = self.get_paginated_response(withdrawal_serializer.data)
                
                # 向分页响应中添加收入信息
                paginated_response.data['income_summary'] = {
                    "total_income": f"{total_income:.2f}",
                    "order_income": f"{order_income:.2f}",
                    "bonus_income": f"{bonus_income:.2f}",
                    "total_withdrawn": f"{total_withdrawn:.2f}",
                    "current_balance": f"{chef_wallet.balance:.2f}"  # 钱包当前余额
                }
                paginated_response.data['recent_income_transactions'] = DjWalletTransactionSerializer(
                    recent_income_transactions, many=True
                ).data
                return paginated_response

            # 7. 不分页时返回完整数据
            withdrawal_serializer = self.get_serializer(withdrawal_records, many=True)
            return Response({
                "count": withdrawal_records.count(),
                "results": withdrawal_serializer.data,
                "income_summary": {
                    "total_income": f"{total_income:.2f}",
                    "order_income": f"{order_income:.2f}",
                    "bonus_income": f"{bonus_income:.2f}",
                    "total_withdrawn": f"{total_withdrawn:.2f}",
                    "current_balance": f"{chef_wallet.balance:.2f}"
                },
                "recent_income_transactions": DjWalletTransactionSerializer(
                    recent_income_transactions, many=True
                ).data
            }, status=status.HTTP_200_OK)
        
            logger.info(f"提现记录序列化数据：{withdrawal_serializer.data}")
              # 收入交易序列化后的数据
            logger.info(f"收入交易序列化数据：{DjWalletTransactionSerializer(recent_income_transactions, many=True).data}")

        except APIException as e:
            return Response(
                {"detail": str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
        except Exception as e:
            logger.error(
                f"用户[{current_user.id if 'current_user' in locals() else '未知'}]查询提现历史失败: {str(e)}",
                exc_info=True
            )
            return Response(
                {"detail": "获取提现记录失败，请稍后重试"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    

class ChefWithdrawalInfoView(APIView):
    """
    厨师提现信息接口
    对应前端getWithdrawalInfo请求，返回：
    - 可提现余额
    - 提现限制（最低金额、单日限额、费率）
    - 默认银行卡信息
    - 可提现状态
    """
    permission_classes = [IsAuthenticated]  # 需登录

    def get(self, request):
        # 1. 打印请求基本信息（用于与前端请求日志对比）
        logger.info(
            f"收到提现信息请求 | "
            f"用户ID: {request.user.id} | "
            f"请求路径: {request.path} | "
            f"请求方法: {request.method} | "
            f"Authorization头: {request.META.get('HTTP_AUTHORIZATION', '无')}"
        )

        try:
            # 关键修复：直接从chefs_djchef表查询与当前用户关联的厨师档案
            # 假设DjChef模型有一个外键字段"user"关联到accounts_user表
            chef_profile = get_object_or_404(DjChef, user=request.user)
            logger.info(f"成功关联厨师档案 | 厨师ID: {chef_profile.id} | 用户ID: {request.user.id}")

            # 通过厨师档案获取钱包（确保DjChef与DjChefWallet正确关联）
            wallet = get_object_or_404(DjChefWallet, chef=chef_profile)
            logger.info(f"获取到钱包信息 | 钱包ID: {wallet.id} | 余额: {wallet.balance}")

            # 获取默认银行卡
            default_card = DjChefBankCard.objects.filter(
                wallet=wallet,
                is_default=True,
                is_valid=True
            ).first()
            card_log = f"默认银行卡ID: {default_card.id}" if default_card else "无默认银行卡"
            logger.info(f"查询默认银行卡 | {card_log}")

            # 构建响应数据
            data = {
                'balance': wallet.balance,
                'available_balance': wallet.available_balance(),  # 确保该方法存在
                'daily_withdraw_limit': wallet.daily_withdraw_limit,
                'min_withdraw_amount': wallet.min_withdraw_amount,
                'withdraw_fee_rate': wallet.withdraw_fee_rate,
                'default_card': default_card,
                'can_withdraw': not wallet.is_locked
            }

            logger.info(
                f"准备返回提现信息 | "
                f"可用余额: {data['available_balance']} | "
                f"最低提现金额: {data['min_withdraw_amount']}"
            )

            serializer = WithdrawalInfoSerializer(data)
            return Response(serializer.data)

        except DjChef.DoesNotExist:
            # 明确捕获厨师档案不存在的情况（403错误的主要原因）
            logger.error(
                f"权限错误 | 当前用户未关联厨师档案 | "
                f"用户ID: {request.user.id}"
            )
            return Response(
                {'error': '当前用户未注册为厨师'}, 
                status=status.HTTP_403_FORBIDDEN
            )
        except Exception as e:
            logger.error(
                f"服务器内部错误 | "
                f"用户ID: {request.user.id} | "
                f"错误信息: {str(e)}",
                exc_info=True
            )
            return Response(
                {'error': '服务器处理失败'}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
          
 #获取银行卡列表 + 创建银行卡         
class BankCardListView(generics.ListCreateAPIView):
    """
    厨师银行卡列表与创建视图（基于chefs应用模型）
    """
    permission_classes = [permissions.IsAuthenticated]

    def get_serializer_class(self):
        return BankCardCreateSerializer if self.request.method == 'POST' else BankCardSerializer

    def dispatch(self, request, *args, **kwargs):
        """重写dispatch方法，在所有请求处理前记录认证基础信息"""
        # 记录请求方法、路径
        logger.info(f"处理{request.method}请求 - 路径: {request.path}")
        # 记录用户认证状态
        logger.info(f"用户认证状态: {'已认证' if request.user.is_authenticated else '未认证'}")
        # 记录请求头中的认证信息（注意脱敏，只保留前缀）
        auth_header = request.META.get('HTTP_AUTHORIZATION', '无')
        logger.info(f"认证头信息: {'Bearer ***' if auth_header.startswith('Bearer ') else auth_header}")
        return super().dispatch(request, *args, **kwargs)

    def get_queryset(self):
        """查询当前厨师的银行卡列表"""
        logger.info(f"进入get_queryset - 当前用户: {self.request.user.username if self.request.user.is_authenticated else '匿名用户'}")
        
        try:
            current_chef = DjChef.objects.get(user=self.request.user)
            logger.info(f"查询到关联厨师 - ID: {current_chef.id}, 用户: {current_chef.user.username}")
        except DjChef.DoesNotExist:
            logger.warning(f"当前用户{self.request.user.username}未关联DjChef记录")
            return DjChefBankCard.objects.none()
        
        queryset = DjChefBankCard.objects.filter(chef_id=current_chef.id).order_by('-id')
        logger.info(f"查询到{queryset.count()}条银行卡记录")
        return queryset

    def list(self, request, *args, **kwargs):
        logger.info("进入list方法 - 获取银行卡列表")
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        response_data = {
            'bank_cards': serializer.data,
            'latest_card': serializer.data[0] if serializer.data else None
        }
        logger.info(f"返回银行卡列表 - 数量: {len(serializer.data)}")
        return Response(response_data)

    def create(self, request, *args, **kwargs):
        # 先确认用户是否已认证（尽管权限类已限制，但二次确认）
        if not request.user.is_authenticated:
            logger.error("创建银行卡失败 - 用户未认证")
            return Response(
                {"detail": "用户未认证"}, 
                status=status.HTTP_401_UNAUTHORIZED
            )
        
        logger.info(f"进入create方法 - 用户: {request.user.username}, 请求数据: {request.data}")
        try:
            serializer = self.get_serializer(data=request.data)
            
            if not serializer.is_valid():
                logger.error(f"序列化器验证失败: {serializer.errors}")
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
            
            response = super().create(request, *args, **kwargs)
            logger.info(f"银行卡创建成功 - 响应数据: {response.data}")
            return response
        except Exception as e:
            logger.error(f"创建银行卡异常: {str(e)}", exc_info=True)
            return Response(
                {"detail": "服务器内部错误"}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def perform_create(self, serializer):
        try:
            logger.info(f"进入perform_create - 用户: {self.request.user.username}")
            # 获取当前厨师
            try:
                current_chef = DjChef.objects.get(user=self.request.user)
                logger.info(f"关联厨师信息 - ID: {current_chef.id}")
            except DjChef.DoesNotExist:
                error_msg = "当前用户未关联厨师信息，请先完成厨师认证"
                logger.error(f"perform_create失败: {error_msg}")
                raise ValueError(error_msg)
            
            # 验证钱包存在
            try:
                wallet = DjChefWallet.objects.get(chef=current_chef)
                logger.info(f"查询到钱包 - ID: {wallet.id}")
            except DjChefWallet.DoesNotExist:
                error_msg = "未找到厨师钱包，请先创建钱包"
                logger.error(f"perform_create失败: {error_msg}")
                raise ValueError(error_msg)
            
            # 处理有效期等逻辑（保持原有）
            validated_data = serializer.validated_data
            bank_code = validated_data.get('bank_code')
            card_number = validated_data.get('card_number')
            expire_date = validated_data.get('expire_date')
            
            if '/' not in expire_date:
                raise ValueError(f"有效期格式错误，预期 MM/YY，实际: {expire_date}")
            expire_month, expire_year = expire_date.split('/')
            if not (expire_month.isdigit() and 1 <= int(expire_month) <= 12):
                raise ValueError(f"无效的月份: {expire_month}")
            if not (expire_year.isdigit() and len(expire_year) == 2):
                raise ValueError(f"无效的年份: {expire_year}，需为两位数字")
            
            last_four = card_number[-4:] if len(card_number) >= 4 else card_number
            bank_name = self._get_bank_name(bank_code)
            
            # 保存数据
            saved_card = serializer.save(
                chef_id=current_chef.id,
                wallet=wallet,
                bank_name=bank_name,
                last_four=last_four,
                expire_date=expire_date
            )
            logger.info(f"银行卡保存成功 - ID: {saved_card.id}, 卡号后四位: {last_four}")

        except Exception as e:
            logger.error(
                f"perform_create异常 - 用户: {self.request.user.username}, 错误: {str(e)}",
                exc_info=True
            )
            raise

    def _get_bank_name(self, code):
        bank_map = {
            'ICBC': '中国工商银行',
            'CCB': '中国建设银行',
            'BOC': '中国银行',
            'CMB': '招商银行',
            'ABC': '中国农业银行',
            'BOCOM': '交通银行',
            'CMBC': '中国民生银行',
            'SPDB': '上海浦东发展银行',
            'CIB': '兴业银行',
            'PAB': '平安银行'
        }
        return bank_map.get(code, '未知银行')

# 2. 设置默认卡视图（单独处理PATCH请求）
class BankCardSetDefaultView(generics.GenericAPIView):
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = BankCardSerializer

    def post(self, request, pk):  
        return self.set_default(request, pk)

    def patch(self, request, pk):
        return self.set_default(request, pk)
    
    def set_default(self, request, pk): 
        user = request.user
        if not hasattr(user, 'djchef_profile'):
            return Response(
                {'detail': '用户未关联厨师信息'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            # 获取当前用户的指定卡片
            card = DjChefBankCard.objects.get(
                id=pk,
                wallet__chef=user.djchef_profile
            )
            
            # 先将所有卡片设为非默认
            DjChefBankCard.objects.filter(
                wallet__chef=user.djchef_profile
            ).update(is_default=False)
            
            # 设置当前卡片为默认
            card.is_default = True
            card.save()
            
            return Response({
                'detail': '设置默认卡片成功',
                'card': BankCardSerializer(card).data
            })
        except DjChefBankCard.DoesNotExist:
            return Response(
                {'detail': '银行卡不存在'},
                status=status.HTTP_404_NOT_FOUND
            )


# 3. 删除银行卡视图（单独处理DELETE请求）
class BankCardDeleteView(generics.DestroyAPIView):
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = BankCardSerializer

    def get_queryset(self):
        # 限制只能删除自己的卡片
        return DjChefBankCard.objects.filter(
            wallet__chef=self.request.user.djchef_profile
        )
    
    def destroy(self, request, *args, **kwargs):
        # 记录删除请求的基本信息
        logger.info(
            f"用户[{request.user.id}]尝试删除银行卡，卡片ID: {kwargs.get('pk')}, "
            f"请求方法: {request.method}, 请求IP: {request.META.get('REMOTE_ADDR')}"
        )
        
        try:
            # 获取要删除的对象
            instance = self.get_object()
            # 记录待删除卡片的详细信息（按需调整记录字段）
            logger.debug(
                f"待删除银行卡信息: ID={instance.id}, "
                f"银行名称={instance.bank_name}, "
                f"尾号={instance.last_four}"
            )
            
            # 执行删除操作
            self.perform_destroy(instance)
            logger.info(f"用户[{request.user.id}]成功删除银行卡，卡片ID: {kwargs.get('pk')}")
            return Response(status=status.HTTP_204_NO_CONTENT)
            
        except Exception as e:
            # 记录错误信息（包括堆栈跟踪）
            logger.error(
                f"用户[{request.user.id}]删除银行卡失败，卡片ID: {kwargs.get('pk')}, "
                f"错误原因: {str(e)}",
                exc_info=True  # 记录完整堆栈信息，便于排查
            )
            return Response(
                {"detail": "删除银行卡失败"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        
class BankCardDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = BankCardSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return DjChefBankCard.objects.filter(
            wallet__chef=self.request.user.djchef
        )

    def perform_destroy(self, instance):
        if instance.is_default:
            raise serializers.ValidationError("不能删除默认银行卡")
        instance.delete()

class WithdrawalListView(generics.ListCreateAPIView):
    serializer_class = WithdrawalSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return DjWithdrawal.objects.filter(
            wallet__chef=self.request.user.djchef
        ).order_by('-requested_at')[:10]

    def perform_create(self, serializer):
        wallet = self.request.user.djchef.payment_wallet
        serializer.save(wallet=wallet)

#厨师端后台部分

class VdjChefWithdrawalListView(generics.ListAPIView):
    """管理系统查看厨师提现列表"""
    serializer_class = WithdrawalSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def get_queryset(self):
        queryset = DjWithdrawal.objects.select_related('wallet__chef')
        
        # 搜索条件
        search = self.request.query_params.get('search', None)
        status = self.request.query_params.get('status', None)
        chef_id = self.request.query_params.get('chef_id', None)
        
        if search:
            queryset = queryset.filter(
                Q(wallet__chef__user__username__icontains=search) |
                Q(wallet__chef__user__phone__icontains=search) |
                Q(account_name__icontains=search)
            )
        
        if status:
            queryset = queryset.filter(status=status)
            
        if chef_id:
            queryset = queryset.filter(wallet__chef_id=chef_id)
            
        return queryset.order_by('-requested_at')

class VdjChefWithdrawalProcessView(generics.UpdateAPIView):
    """管理系统处理提现申请"""
    queryset = DjWithdrawal.objects.all()
    serializer_class = ChefWithdrawalSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        action = request.data.get('action')
        
        if action == 'approve':
            if instance.status != 'pending':
                return Response(
                    {'error': '只有待处理状态的提现可以审核'},
                    status=status.HTTP_400_BAD_REQUEST
                )
                
            # 执行提现逻辑 (这里简化处理，实际应调用支付网关)
            instance.status = 'processing'
            instance.save()
            
            # TODO: 实际项目中这里应调用支付网关API执行转账
            
            # 模拟转账成功
            instance.status = 'completed'
            instance.processed_at = timezone.now()
            instance.save()
            
            # 更新钱包冻结金额
            wallet = instance.wallet
            wallet.frozen_amount -= instance.amount
            wallet.total_withdrawn += instance.amount
            wallet.save()
            
            return Response(
                {'message': '提现申请已批准并处理完成'},
                status=status.HTTP_200_OK
            )
            
        elif action == 'reject':
            if instance.status != 'pending':
                return Response(
                    {'error': '只有待处理状态的提现可以拒绝'},
                    status=status.HTTP_400_BAD_REQUEST
                )
                
            instance.status = 'failed'
            instance.failure_reason = request.data.get('reason', '审核不通过')
            instance.processed_at = timezone.now()
            instance.save()
            
            # 解冻金额并退回余额
            wallet = instance.wallet
            wallet.frozen_amount -= instance.amount
            wallet.balance += instance.amount
            wallet.save()
            
            return Response(
                {'message': '提现申请已拒绝'},
                status=status.HTTP_200_OK
            )
            
        return Response(
            {'error': '无效的操作'},
            status=status.HTTP_400_BAD_REQUEST
        )

class VdjChefWalletListView(generics.ListAPIView):
    """管理系统查看厨师钱包列表"""
    serializer_class = ChefWalletSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def get_queryset(self):
        queryset = DjChefWallet.objects.select_related('chef__user')
        
        # 搜索条件
        search = self.request.query_params.get('search', None)
        chef_id = self.request.query_params.get('chef_id', None)
        min_balance = self.request.query_params.get('min_balance')
        max_balance = self.request.query_params.get('max_balance')
        is_locked = self.request.query_params.get('is_locked')
        
        if search:
            queryset = queryset.filter(
                Q(chef__user__username__icontains=search) |
                Q(chef__user__phone__icontains=search)
            )
            
        if chef_id:
            queryset = queryset.filter(chef_id=chef_id)

        if min_balance:
            queryset = queryset.filter(balance__gte=min_balance)
        if max_balance:
            queryset = queryset.filter(balance__lte=max_balance)
        if is_locked:
            queryset = queryset.filter(is_locked=is_locked.lower() == 'true')
            
        return queryset.order_by('-balance')